/*
 * Copyright 2010 Chad Retz
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package org.jdocng.parse.qdox.function;

import java.util.ArrayList;
import java.util.List;

import org.jdocng.parse.qdox.QDoxContext;
import org.jdocng.shared.model.ClassDocImpl;
import org.jdocng.shared.model.ConstructorDocImpl;
import org.jdocng.shared.model.FieldDocImpl;
import org.jdocng.shared.model.MethodDocImpl;

import com.thoughtworks.qdox.model.JavaClass;
import com.thoughtworks.qdox.model.JavaField;
import com.thoughtworks.qdox.model.JavaMethod;

/**
 * Construct {@link ClassDocImpl} from {@link JavaClass}
 *
 * @author Chad Retz
 */
public class ClassFunction<T extends ClassDocImpl> 
        extends ProgramElementFunction<JavaClass, T> {

    private static final ClassFunction<ClassDocImpl> instance = 
        new ClassFunction<ClassDocImpl>();
    
    public static ClassFunction<? extends ClassDocImpl> getFunction(
            JavaClass cls) {
        //TODO: what?
        if (cls.getName().startsWith("@")) {
            return AnnotationTypeFunction.getInstance();
        } else {
            return instance;
        }
    }
    
    protected ClassFunction() {
    }
    
    @Override
    @SuppressWarnings("unchecked")
    public T apply(QDoxContext context, JavaClass from) {
        ClassDocImpl to = new ClassDocImpl();
        apply(context, from, (T) to);
        //persist
        context.getClasses().put(to.name(), to);
        context.getTypes().put(to.name(), to);
        return (T) to;
    }
    
    @Override
    @SuppressWarnings("unused")
    public void apply(QDoxContext context, JavaClass from, T to) {
        super.apply(context, from, to);
        List<ConstructorDocImpl> constructors = new ArrayList<ConstructorDocImpl>();
        List<MethodDocImpl> methods = new ArrayList<MethodDocImpl>(
                from.getMethods().length);
        for (JavaMethod method : from.getMethods()) {
            if (method.isConstructor()) {
                constructors.add(ConstructorFunction.getInstance().apply(context, method));
            } else {
                methods.add(MethodFunction.getInstance().apply(context, method));
            }
        }
        to.setConstructors(constructors.toArray(new ConstructorDocImpl[0]));
        to.setMethods(methods.toArray(new MethodDocImpl[0]));
        //TODO defines serializable fields
        //enum constants
        List<FieldDocImpl> enumConstants = new ArrayList<FieldDocImpl>();
        List<FieldDocImpl> fields = new ArrayList<FieldDocImpl>(from.getFields().length);
        for (JavaField field : from.getFields()) {
            //TODO enum constants
        }
        //TODO the rest of this
        throw new UnsupportedOperationException();
    }

}
